/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.utils
{
	import com.puny.mvc.views.platformer.movieclips.ObjectView;
	
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class CollisionPt extends Point {
		public static const FROM_LEFT:int   = 0x0001;
		public static const FROM_RIGHT:int  = 0x0010;
		public static const FROM_TOP:int    = 0x0100;
		public static const FROM_BOTTOM:int = 0x1000;
		private var _t:Number;
		private var _direction:int;
		
		public static function collisionRect(me:ObjectView, target:ObjectView):Rectangle {
			return new Rectangle(int((target.x - me.half.x)*100)/100,
							     int((target.y - me.half.y)*100)/100,
								 int((me.width + target.width)*100)/100,
								 int((me.height + target.height)*100)/100);
		} 
		public function CollisionPt(direction:int) {
//			trace("me:",me.x,me.y,me.width,me.height);
//			trace("target:",target.x,target.y,target.width,target.height);
//			trace("v:",v.x,v.y);
			super(0, 0);
			_direction = direction;
		}
		
		public function check(me:ObjectView,target:ObjectView,v:Point,rect:Rectangle):void {
			var s:Number;
			var limit:Number = 0;
			if ((_direction & FROM_TOP)  > 0) {
				s = horizontal(me,rect,v,rect.y);
				limit = rect.width;
				if (_t == 0 && v.y < 0) {
					_t = Infinity;
				}
			} else if ((_direction & FROM_BOTTOM) > 0) {
				s = horizontal(me,rect,v,rect.y+rect.height);
				limit = rect.width;
				if (_t == 0 && v.y > 0) {
					_t = Infinity;
				}
			} else if ((_direction & FROM_LEFT) > 0) {
				s = vertical(me,rect,v,rect.x);
				limit = rect.height;
				if (_t == 0 && v.x < 0) {
					_t = Infinity;
				}
			} else if ((_direction & FROM_RIGHT) > 0) {
				s = vertical(me,rect,v,rect.x+rect.width);
				limit = rect.height;
				if (_t == 0 && v.x > 0) {
					_t = Infinity;
				}
			}
			if (s < 0 || s > limit) {
				_t = Infinity;
				return;
			}
		}
		
		private function horizontal(me:ObjectView,target:Rectangle,v:Point,targetHeight:Number):Number {
			if (v.y == 0) {
				return Infinity;
			}
			_t = int((targetHeight - me.center.y) / v.y * 100) / 100;
			if (_t < 0 || _t > 1) {
				return Infinity;
			}
			var s:Number = (me.center.x - target.x) + v.x * _t;
			x = target.x + s;
			y = targetHeight;
			return s;
		}

		private function vertical(me:ObjectView,target:Rectangle,v:Point,targetWidth:Number):Number {
			if (v.x == 0) {
				return Infinity;
			}
			_t = int((targetWidth - me.center.x) / v.x * 100) / 100;
			if (_t < 0 || _t > 1) {
				return Infinity;
			}
			var s:Number = (me.center.y - target.y) + v.y *_t;
			x = targetWidth;
			y = target.y + s;
			return s;
		}		

		public function get time():Number {
			return _t;
		}
		
		public function isHorizontal():Boolean {
			return (_direction & (FROM_TOP | FROM_BOTTOM)) > 0;
		}
		
		public function isVertical():Boolean {
			return (_direction & (FROM_LEFT | FROM_RIGHT)) > 0;
		}
	}
}